package com.beerandjesus.sportofkings.handicapper.profile.resolver;

import com.beerandjesus.sportofkings.handicapper.dao.Database;
import com.beerandjesus.sportofkings.handicapper.profile.AnalysisProfile;
import com.beerandjesus.sportofkings.handicapper.profile.AnalysisProfileBuilder;
import com.beerandjesus.sportofkings.handicapper.model.*;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Horse;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.HorseRace;
import com.beerandjesus.sportofkings.handicapper.strategy.RacingCalculator;
import com.beerandjesus.sportofkings.handicapper.strategy.brisnet.singlefile.KeyTrainerStatisticsResolver;

import java.math.BigDecimal;

import static com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.KeyTrainerStatisticsCategory.*;
import static com.beerandjesus.sportofkings.handicapper.profile.AnalysisProfile.Type.*;

/**
 * This profile identifies first and second time starters on dirt or artificial surfaces who
 * meet the following criteria:
 *
 * - sire and dam's sire show a higher than average rating (Brisnet SPI)
 * - sire's foals win at 10% clip or higher
 * - trainer wins with 1st/2nd time starters (as appropriate) at 10% clip or higher
 *
 * See this article for all the details:
 *
 * http://www.brisnet.com/cgi-bin/static.cgi?page=incorporating_Sp1_and_dpi_into_handicapping_maiden_25Sep07
 *
 */
public class FirstOr2ndStartersOnDirtProfileResolver implements AnalysisProfileResolver {
    private Database database;
    private KeyTrainerStatisticsResolver keyTrainerStatisticsResolver = new KeyTrainerStatisticsResolver();
    private RacingCalculator calc = new RacingCalculator();

    public FirstOr2ndStartersOnDirtProfileResolver(Database database) {
        this.database = database;
    }

    public AnalysisProfile resolve(HorseRace race, Horse horse) {
        // Profile applies to 1st or 2nd starter on dirt or artificial surface
        if (!horse.isFirstOrSecondTimeStarter() || race.getRace().getSurface().isTurf()) {
            return null;
        }
        // Trainer must win with 1st/2nd starters at 10%+ clip
        TrainerJockeyOwner tjo = horse.getTrainerJockeyOwner();
        if (tjo == null) {
            return null;
        }
        KeyTrainerStatistics stats = keyTrainerStatisticsResolver.getKeyTrainerStatistics(tjo.getKeyTrainerStatistics(), race.getRace().getType(),
                (horse.getPastPerformances() == null ? 0 : horse.getPastPerformances().size()));
        if (stats == null) {
            return null;
        }
        Float winPercentage = calc.getFloatOrZero(stats.getWinPercentage());
        if (!isFirstOrSecondStarterTrainerStats(stats)
                || winPercentage.compareTo(10f) <= 0) {
            return null;
        }
        // Sire and dam's sire must have a Rating > 1.00 (this is currently Brisnet SPI)
        String sireName = horse.getSireName();
        String damSireName = horse.getDamSireName();
        Sire sire = database.getDirtArtificialSireByName(sireName);
        Sire damSire = database.getDirtArtificialSireByName(damSireName);
        if (sire == null || damSire == null || sire.getRating() == null || damSire.getRating() == null) {
            return null;
        }
        if (sire.getRating().compareTo(BigDecimal.ONE) <= 0
                || damSire.getRating().compareTo(BigDecimal.ONE) <= 0) {
            return null;
        }
        // Sire's foals must win at 10%+ clip
        if (sire.getWinPercentage().compareTo(new BigDecimal(.10)) <= 0) {
            return null;
        }
        return AnalysisProfileBuilder.analysisProfile(FIRST_OR_2ND_DIRT_STARTER_WITH_PEDIGREE, 1);
    }

    private boolean isFirstOrSecondStarterTrainerStats(KeyTrainerStatistics stats) {
        return stats.getCategory().equals(STAT_2ND_CAREER_RACE) || stats.getCategory().equals(STAT_1ST_TIME_STR);
    }
}
